﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IPC.Communication.BasicFramework;

namespace IPC.Communication.Core
{
    public class ByteTransformBase : IByteTransform
    {
        public DataFormat DataFormat
        {
            get;
            set;
        }

        public bool IsStringReverseByteWord
        {
            get;
            set;
        }

        public ByteTransformBase()
        {
            this.DataFormat = DataFormat.DCBA;
        }

        public ByteTransformBase(DataFormat dataFormat)
        {
            this.DataFormat = dataFormat;
        }

        public virtual bool TransBool(byte[] buffer, int index)
        {
            return (buffer[index] & 1) == 1;
        }

        public bool[] TransBool(byte[] buffer, int index, int length)
        {
            byte[] array = new byte[length];
            Array.Copy(buffer, index, array, 0, length);
            return SoftBasic.ByteToBoolArray(array, length * 8);
        }

        public virtual byte TransByte(byte[] buffer, int index)
        {
            return buffer[index];
        }

        public virtual byte[] TransByte(byte[] buffer, int index, int length)
        {
            byte[] array = new byte[length];
            Array.Copy(buffer, index, array, 0, length);
            return array;
        }

        public virtual short TransInt16(byte[] buffer, int index)
        {
            return BitConverter.ToInt16(buffer, index);
        }

        public virtual short[] TransInt16(byte[] buffer, int index, int length)
        {
            short[] array = new short[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransInt16(buffer, index + 2 * i);
            }
            return array;
        }

        public short[,] TransInt16(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<short>(this.TransInt16(buffer, index, row * col), row, col);
        }

        public virtual ushort TransUInt16(byte[] buffer, int index)
        {
            return BitConverter.ToUInt16(buffer, index);
        }

        public virtual ushort[] TransUInt16(byte[] buffer, int index, int length)
        {
            ushort[] array = new ushort[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransUInt16(buffer, index + 2 * i);
            }
            return array;
        }

        public ushort[,] TransUInt16(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<ushort>(this.TransUInt16(buffer, index, row * col), row, col);
        }

        public virtual int TransInt32(byte[] buffer, int index)
        {
            return BitConverter.ToInt32(this.ByteTransDataFormat4(buffer, index), 0);
        }

        public virtual int[] TransInt32(byte[] buffer, int index, int length)
        {
            int[] array = new int[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransInt32(buffer, index + 4 * i);
            }
            return array;
        }

        public int[,] TransInt32(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<int>(this.TransInt32(buffer, index, row * col), row, col);
        }

        public virtual uint TransUInt32(byte[] buffer, int index)
        {
            return BitConverter.ToUInt32(this.ByteTransDataFormat4(buffer, index), 0);
        }

        public virtual uint[] TransUInt32(byte[] buffer, int index, int length)
        {
            uint[] array = new uint[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransUInt32(buffer, index + 4 * i);
            }
            return array;
        }

        public uint[,] TransUInt32(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<uint>(this.TransUInt32(buffer, index, row * col), row, col);
        }

        public virtual long TransInt64(byte[] buffer, int index)
        {
            return BitConverter.ToInt64(this.ByteTransDataFormat8(buffer, index), 0);
        }

        public virtual long[] TransInt64(byte[] buffer, int index, int length)
        {
            long[] array = new long[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransInt64(buffer, index + 8 * i);
            }
            return array;
        }

        public long[,] TransInt64(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<long>(this.TransInt64(buffer, index, row * col), row, col);
        }

        public virtual ulong TransUInt64(byte[] buffer, int index)
        {
            return BitConverter.ToUInt64(this.ByteTransDataFormat8(buffer, index), 0);
        }

        public virtual ulong[] TransUInt64(byte[] buffer, int index, int length)
        {
            ulong[] array = new ulong[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransUInt64(buffer, index + 8 * i);
            }
            return array;
        }

        public ulong[,] TransUInt64(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<ulong>(this.TransUInt64(buffer, index, row * col), row, col);
        }

        public virtual float TransSingle(byte[] buffer, int index)
        {
            return BitConverter.ToSingle(this.ByteTransDataFormat4(buffer, index), 0);
        }

        public virtual float[] TransSingle(byte[] buffer, int index, int length)
        {
            float[] array = new float[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransSingle(buffer, index + 4 * i);
            }
            return array;
        }

        public float[,] TransSingle(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<float>(this.TransSingle(buffer, index, row * col), row, col);
        }

        public virtual double TransDouble(byte[] buffer, int index)
        {
            return BitConverter.ToDouble(this.ByteTransDataFormat8(buffer, index), 0);
        }

        public virtual double[] TransDouble(byte[] buffer, int index, int length)
        {
            double[] array = new double[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = this.TransDouble(buffer, index + 8 * i);
            }
            return array;
        }

        public double[,] TransDouble(byte[] buffer, int index, int row, int col)
        {
            return HslHelper.CreateTwoArrayFromOneArray<double>(this.TransDouble(buffer, index, row * col), row, col);
        }

        public virtual string TransString(byte[] buffer, int index, int length, Encoding encoding)
        {
            byte[] array = this.TransByte(buffer, index, length);
            bool isStringReverseByteWord = this.IsStringReverseByteWord;
            string @string;
            if (isStringReverseByteWord)
            {
                @string = encoding.GetString(SoftBasic.BytesReverseByWord(array));
            }
            else
            {
                @string = encoding.GetString(array);
            }
            return @string;
        }

        public virtual string TransString(byte[] buffer, Encoding encoding)
        {
            return encoding.GetString(buffer);
        }

        public virtual byte[] TransByte(bool value)
        {
            return this.TransByte(new bool[]
			{
				value
			});
        }

        public virtual byte[] TransByte(bool[] values)
        {
            return (values == null) ? null : SoftBasic.BoolArrayToByte(values);
        }

        public virtual byte[] TransByte(byte value)
        {
            return new byte[]
			{
				value
			};
        }

        public virtual byte[] TransByte(short value)
        {
            return this.TransByte(new short[]
			{
				value
			});
        }

        public virtual byte[] TransByte(short[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 2];
                for (int i = 0; i < values.Length; i++)
                {
                    BitConverter.GetBytes(values[i]).CopyTo(array, 2 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(ushort value)
        {
            return this.TransByte(new ushort[]
			{
				value
			});
        }

        public virtual byte[] TransByte(ushort[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 2];
                for (int i = 0; i < values.Length; i++)
                {
                    BitConverter.GetBytes(values[i]).CopyTo(array, 2 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(int value)
        {
            return this.TransByte(new int[]
			{
				value
			});
        }

        public virtual byte[] TransByte(int[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 4];
                for (int i = 0; i < values.Length; i++)
                {
                    this.ByteTransDataFormat4(BitConverter.GetBytes(values[i]), 0).CopyTo(array, 4 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(uint value)
        {
            return this.TransByte(new uint[]
			{
				value
			});
        }

        public virtual byte[] TransByte(uint[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 4];
                for (int i = 0; i < values.Length; i++)
                {
                    this.ByteTransDataFormat4(BitConverter.GetBytes(values[i]), 0).CopyTo(array, 4 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(long value)
        {
            return this.TransByte(new long[]
			{
				value
			});
        }

        public virtual byte[] TransByte(long[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 8];
                for (int i = 0; i < values.Length; i++)
                {
                    this.ByteTransDataFormat8(BitConverter.GetBytes(values[i]), 0).CopyTo(array, 8 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(ulong value)
        {
            return this.TransByte(new ulong[]
			{
				value
			});
        }

        public virtual byte[] TransByte(ulong[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 8];
                for (int i = 0; i < values.Length; i++)
                {
                    this.ByteTransDataFormat8(BitConverter.GetBytes(values[i]), 0).CopyTo(array, 8 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(float value)
        {
            return this.TransByte(new float[]
			{
				value
			});
        }

        public virtual byte[] TransByte(float[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 4];
                for (int i = 0; i < values.Length; i++)
                {
                    this.ByteTransDataFormat4(BitConverter.GetBytes(values[i]), 0).CopyTo(array, 4 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(double value)
        {
            return this.TransByte(new double[]
			{
				value
			});
        }

        public virtual byte[] TransByte(double[] values)
        {
            bool flag = values == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] array = new byte[values.Length * 8];
                for (int i = 0; i < values.Length; i++)
                {
                    this.ByteTransDataFormat8(BitConverter.GetBytes(values[i]), 0).CopyTo(array, 8 * i);
                }
                result = array;
            }
            return result;
        }

        public virtual byte[] TransByte(string value, Encoding encoding)
        {
            bool flag = value == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] bytes = encoding.GetBytes(value);
                result = (this.IsStringReverseByteWord ? SoftBasic.BytesReverseByWord(bytes) : bytes);
            }
            return result;
        }

        public virtual byte[] TransByte(string value, int length, Encoding encoding)
        {
            bool flag = value == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                byte[] bytes = encoding.GetBytes(value);
                result = (this.IsStringReverseByteWord ? SoftBasic.ArrayExpandToLength<byte>(SoftBasic.BytesReverseByWord(bytes), length) : SoftBasic.ArrayExpandToLength<byte>(bytes, length));
            }
            return result;
        }

        protected byte[] ByteTransDataFormat4(byte[] value, int index = 0)
        {
            byte[] array = new byte[4];
            switch (this.DataFormat)
            {
                case DataFormat.ABCD:
                    array[0] = value[index + 3];
                    array[1] = value[index + 2];
                    array[2] = value[index + 1];
                    array[3] = value[index];
                    break;
                case DataFormat.BADC:
                    array[0] = value[index + 2];
                    array[1] = value[index + 3];
                    array[2] = value[index];
                    array[3] = value[index + 1];
                    break;
                case DataFormat.CDAB:
                    array[0] = value[index + 1];
                    array[1] = value[index];
                    array[2] = value[index + 3];
                    array[3] = value[index + 2];
                    break;
                case DataFormat.DCBA:
                    array[0] = value[index];
                    array[1] = value[index + 1];
                    array[2] = value[index + 2];
                    array[3] = value[index + 3];
                    break;
            }
            return array;
        }

        protected byte[] ByteTransDataFormat8(byte[] value, int index = 0)
        {
            byte[] array = new byte[8];
            switch (this.DataFormat)
            {
                case DataFormat.ABCD:
                    array[0] = value[index + 7];
                    array[1] = value[index + 6];
                    array[2] = value[index + 5];
                    array[3] = value[index + 4];
                    array[4] = value[index + 3];
                    array[5] = value[index + 2];
                    array[6] = value[index + 1];
                    array[7] = value[index];
                    break;
                case DataFormat.BADC:
                    array[0] = value[index + 6];
                    array[1] = value[index + 7];
                    array[2] = value[index + 4];
                    array[3] = value[index + 5];
                    array[4] = value[index + 2];
                    array[5] = value[index + 3];
                    array[6] = value[index];
                    array[7] = value[index + 1];
                    break;
                case DataFormat.CDAB:
                    array[0] = value[index + 1];
                    array[1] = value[index];
                    array[2] = value[index + 3];
                    array[3] = value[index + 2];
                    array[4] = value[index + 5];
                    array[5] = value[index + 4];
                    array[6] = value[index + 7];
                    array[7] = value[index + 6];
                    break;
                case DataFormat.DCBA:
                    array[0] = value[index];
                    array[1] = value[index + 1];
                    array[2] = value[index + 2];
                    array[3] = value[index + 3];
                    array[4] = value[index + 4];
                    array[5] = value[index + 5];
                    array[6] = value[index + 6];
                    array[7] = value[index + 7];
                    break;
            }
            return array;
        }

        public virtual IByteTransform CreateByDateFormat(DataFormat dataFormat)
        {
            return this;
        }

        public override string ToString()
        {
            return string.Format("ByteTransformBase[{0}]", this.DataFormat);
        }
    }
}
